---
description: 'Require `.toString()` and `.toLocaleString()` to only be called on objects which provide useful information when stringified.'
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

> 🛑 This file is source code, not the primary documentation location! 🛑
>
> See **https://typescript-eslint.io/rules/no-base-to-string** for documentation.

JavaScript will call `toString()` on an object when it is converted to a string, such as when concatenated with a string (`expr + ''`), when interpolated into template literals (`${expr}`), or when passed as an argument to the String constructor (`String(expr)`).
The default Object `.toString()` and `toLocaleString()` use the format `"[object Object]"`, which is often not what was intended.
This rule reports on stringified values that aren't primitives and don't define a more useful `.toString()` or `toLocaleString()` method.

> Note that `Function` provides its own `.toString()` and `toLocaleString()` that return the function's code.
> Functions are not flagged by this rule.

## Examples

<Tabs>
<TabItem value="❌ Incorrect">

```ts
// Passing an object or class instance to string concatenation:
'' + {};

class MyClass {}
const value = new MyClass();
value + '';

// Interpolation and manual .toString() and `toLocaleString()` calls too:
`Value: ${value}`;
String({});
({}).toString();
({}).toLocaleString();

// Stringifying objects or instances in an array with the `Array.prototype.join`.
[{}, new MyClass()].join('');
```

</TabItem>
<TabItem value="✅ Correct">

```ts
// These types all have useful .toString() and `toLocaleString()` methods
'Text' + true;
`Value: ${123}`;
`Arrays too: ${[1, 2, 3]}`;
(() => {}).toString();
String(42);
(() => {}).toLocaleString();

// Defining a custom .toString class is considered acceptable
class CustomToString {
  toString() {
    return 'Hello, world!';
  }
}
`Value: ${new CustomToString()}`;

const literalWithToString = {
  toString: () => 'Hello, world!',
};

`Value: ${literalWithToString}`;
```

</TabItem>
</Tabs>

## Alternatives

Consider using `JSON.stringify` when you want to convert non-primitive things to string for logging, debugging, etc.

```typescript
declare const o: object;
const errorMessage = 'Found unexpected value: ' + JSON.stringify(o);
```

## Options

### `ignoredTypeNames`

{/* insert option description */}

This is useful for types missing `toString()` or `toLocaleString()` (but actually has `toString()` or `toLocaleString()`).
There are some types missing `toString()` or `toLocaleString()` in old versions of TypeScript, like `RegExp`, `URL`, `URLSearchParams` etc.

The following patterns are considered correct with the default options `{ ignoredTypeNames: ["RegExp"] }`:

```ts option='{ "ignoredTypeNames": ["RegExp"] }' showPlaygroundButton
`${/regex/}`;
'' + /regex/;
/regex/.toString();
let value = /regex/;
value.toString();
let text = `${value}`;
String(/regex/);
```

### `checkUnknown`

{/* insert option description */}

The following patterns are considered incorrect with the options `{ checkUnknown: true }`:

```ts option='{ "checkUnknown": true }' showPlaygroundButton
declare const x: unknown;
String(x);
```

## When Not To Use It

If you don't mind a risk of `"[object Object]"` or incorrect type coercions in your values, then you will not need this rule.

## Related To

- [`restrict-plus-operands`](./restrict-plus-operands.mdx)
- [`restrict-template-expressions`](./restrict-template-expressions.mdx)

## Further Reading

- [`Object.prototype.toString()` MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString)
- [`Object.prototype.toLocaleString()` MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toLocaleString)
- [Microsoft/TypeScript Add missing toString declarations for base types that have them](https://github.com/microsoft/TypeScript/issues/38347)
